//
//  schedule.h
//  Schedule
//
//  Created by Julius Canute on 2/15/12.
//  Copyright 2012 ABB. All rights reserved.
//
#include<iostream>
#include<vector>
#include<map>
#include<queue>
#include<list>
using namespace std;
//class component;
/*
class application;
class node;
class component;
class sequence;
class processor;
class search_space;
class application;
*/
//extern vector <application> apps;
void generate_output_host();
class component{
public:
	int ex_time;
	int app_no;
	int comp_no;
	string comp_name;
	component(){
		ex_time=0;
		app_no=0;
		comp_no=0;
	}
	component(int e,int a,int c){
		ex_time = e;
		app_no = a;
		comp_no = c;
	}
};
class node{
public:
	int cycle_time;
	int node_no;
	string offset;
	node(){
		cycle_time = 0;
	}
	node(int c,int n){
		cycle_time = c;
		node_no = n;
	}
	vector<component> assign;	
};
/*
class component{
public:
	int ex_time;
	int app_no;
	int comp_no;
	component(){
		ex_time=0;
		app_no=0;
		comp_no=0;
	}
	component(int e,int a,int c){
		ex_time = e;
		app_no = a;
		comp_no = c;
	}
};
*/
class sequence{
public:
	sequence(const sequence &s){
        	app_no = s.app_no;
		comp_no = s.comp_no;
        	start_time = s.start_time;
	}
	sequence(int a,int c)
	{
		app_no = a;
		comp_no = c;
	}
	int app_no;
	int comp_no;
	int start_time;
};
class processor{
public:
	int node_no;
	int left_capacity;
	string unit;
	processor(const processor &p){
		node_no = p.node_no;
		left_capacity = p.left_capacity;
		unit  = p.unit;
		assign = p.assign;
	}
	processor(){
		node_no = left_capacity = 0;
	}
    
	processor(int n,int c){
		node_no = n;
		left_capacity = c;
	}
    
	vector <sequence> assign;
    
	void add_assignment(int a,int c){
		assign.push_back(sequence(a,c));
	}
	void add_assignment_obj(sequence s){
        int pos = 0;
        //cout<<"Assigning Component:"<<s.start_time<<endl;
		//assign.push_back(s);
        for (; pos<assign.size(); ) {
          if(s.start_time<assign[pos].start_time)
          {
              break;
          }
          else if(s.start_time == assign[pos].start_time && assign[pos].app_no == -1)
          {
              //cout<<"Inside negative with POS:"<<pos<<endl;
              //if(pos>1)
                  //pos--;
              pos++;
              break;
              
          }
          else if(s.start_time == assign[pos].start_time)
          {
              cout<<"INVALID ASSIGNMENT :( "<<"s.start_time"<<s.start_time<<" "<<assign[pos].start_time<<endl;
          }
          else
              pos++;
        }
        
        
        assign.insert(assign.begin() + pos, s);

	}
    
};
class application{
public:
	application(){
		cycle_time = 0;
		pos = 0;
	}
	application(int c){
		cycle_time = c;
		pos = 0;
	}
	int cycle_time;
	int pos;
	string unit;
	string app_name;
	vector <component> order;
	vector <node*> node_list;
	bool operator() (const application& lhs, const application& rhs) const
        {return lhs.cycle_time<rhs.cycle_time;}
};


void generate_xml_output_host(vector <application> &apps, vector <processor> &p);
class search_space{
public:
	search_space(int n){
		p.resize(n);
	}
	void resize_app_space(int s){
		a.resize(s);
        est.resize(s);
	}
	search_space(const search_space &s){
		p = s.p;
		a = s.a;
		est = s.est;
	}
	vector <processor> p;
	vector <int> a;
	vector <int> est;
    
    void print_node(vector <application> &apps){
        
        for (int i=0; i<p.size(); i++) {
            cout<<"Processor("<<i<<")"<<endl;
            for (int j=0; j<p[i].assign.size(); j++) {
                if(p[i].assign[j].app_no != -1)
                    cout<<" APPNAME "<<apps[p[i].assign[j].app_no].app_name<<" COMPNAME "<<apps[p[i].assign[j].app_no].order[p[i].assign[j].comp_no].comp_name<<" STTIME "<<p[i].assign[j].start_time<<" UNIT "<<p[i].unit<<endl;
            }
            //cout<<"---------------------------------------------------------"<<endl;
        }
    }
    
    
    
    void print_search_node(vector <application> &apps){

	generate_xml_output_host(apps,p);
        for (int i=0; i<p.size(); i++) {
            cout<<"Processor("<<i<<")"<<endl;
            for (int j=0; j<p[i].assign.size(); j++) {
                if(p[i].assign[j].app_no != -1)
                    cout<<" APPNAME "<<apps[p[i].assign[j].app_no].app_name<<" COMPNAME "<<apps[p[i].assign[j].app_no].order[p[i].assign[j].comp_no].comp_name<<" STTIME "<<p[i].assign[j].start_time<<" UNIT "<<p[i].unit<<endl;
            }
            //cout<<"---------------------------------------------------------"<<endl;
        }
    }
};


